#include <stdlib.h>
#include <string.h>

#include "QueueNetworkModel.h"
#include "QueueNetworkModelBuilder.h"
#include "Config.h"

ServerFacility *buildServerFacility (char * name){
    ServerFacility * sf = (ServerFacility*)malloc(sizeof(ServerFacility));
    sf->name = (char*)malloc(sizeof(char)*strlen(name)+1);
    strcpy(sf->name, name);
    sf->cpu = facility(CPU_FACILITY_NAME);
    sf->disk = facility(DISK_FACILITY_NAME);
    return sf;
}

LocalAreaFacility * buildLocalAreaFacility (char * name, ServerFacility** server, int server_len){
    LocalAreaFacility * lf = (LocalAreaFacility*)malloc(sizeof(LocalAreaFacility));
    lf->name = (char *)malloc(sizeof(char)*strlen(name)+1);
    char * c_name = (char *) malloc(sizeof(char)*strlen(name)+10);

    strcpy(lf->name, name);
    lf->lan = facility(LAN_FACILITY_NAME);
    lf->web_switch = facility(WEB_SWITCH_FACILITY);
    lf->n_servers = server_len;
    lf->servers = server;

    lf->local_area_response_time = table(name);

    int i;

#if (STOCHASTIC_SIMULATION) && (STOCHASTIC_SIZE) && (STOCHASTIC_CLUSTERIZED_SIZE)
    lf->local_area_class_response_time = (TABLE*)malloc(sizeof(TABLE)*N_CLASS_STOCHASTIC);
    lf->n_class = N_CLASS_STOCHASTIC;

    for(i=0; i<N_CLASS_STOCHASTIC; i++){
        sprintf(c_name, "class: %s_%d", name, i);
        lf->local_area_class_response_time[i]= table(c_name);
    }
#else
    lf->local_area_class_response_time = (TABLE*)malloc(sizeof(TABLE)*N_CLASS);
    lf->n_class = N_CLASS;

    for(i=0; i<N_CLASS; i++){
        sprintf(c_name, "class: %s_%d", name, i);
        lf->local_area_class_response_time[i]= table(c_name);
    }
#endif

    return lf;
}

NetworkFacility * buildNetworkFacility (char * name, LocalAreaFacility ** local_areas, int n_loc_areas){
    NetworkFacility * nf = (NetworkFacility*)malloc(sizeof(NetworkFacility));
    nf->name = (char *)malloc(sizeof(char)*strlen(name)+1);
    char * c_name = (char *) malloc(sizeof(char)*strlen(name)+10);

    strcpy(nf->name, name);
    nf->n_loc_areas = n_loc_areas;
    nf->local_areas = local_areas;
    nf->network_response_time = table(name);

    nf->link_cdd = facility(LINK_TO_CDD);
    nf->link_in = facility(LINK_IN);
    nf->link_out = facility(LINK_OUT);

    int i;

#if (STOCHASTIC_SIMULATION) && (STOCHASTIC_SIZE) && (STOCHASTIC_CLUSTERIZED_SIZE)
    nf->network_class_response_time = (TABLE*)malloc(sizeof(TABLE)*N_CLASS_STOCHASTIC);
    nf->n_class = N_CLASS_STOCHASTIC;

    for(i=0; i<N_CLASS_STOCHASTIC; i++){
        sprintf(c_name, "class: %s_%d", name, i);
        nf->network_class_response_time[i]= table(c_name);
    }
#else
    nf->network_class_response_time = (TABLE*)malloc(sizeof(TABLE)*N_CLASS);
    nf->n_class = N_CLASS;

    for(i=0; i<N_CLASS; i++){
        sprintf(c_name, "class: %s_%d", name, i);
        nf->network_class_response_time[i]= table(c_name);
    }
#endif
    return nf;
}

void buildQueueNetworkModel(){
    printf("Building Queue Network Model\n");

    char buffer[40];
    LocalAreaFacility **lf = (LocalAreaFacility**)malloc(sizeof(LocalAreaFacility*)*N_LOCAL_AREA);
    int i, j;

    for(i=0; i<N_LOCAL_AREA; i++){
        ServerFacility **sf = (ServerFacility **)malloc(server_per_cluster[i]*sizeof(ServerFacility *));

        for(j=0; j<server_per_cluster[i]; j++){
            sprintf(buffer, "%s_%d", cluster_name[i], j );
            sf[j] = buildServerFacility(buffer);
        }

        sprintf(buffer, "%s", cluster_name[i]);
        lf[i] = buildLocalAreaFacility(buffer, sf, server_per_cluster[i]);
    }

    network_facility = buildNetworkFacility("worldcup98", lf, N_LOCAL_AREA);

    printf("Building Queue Network Model Finished\n");
}